// Copyright (C) 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


#include "auth.h"
#include "http_interact.h"
#include "xml_writer.h"

using std::stringstream;

namespace googleapps {

static const char kCreateAccountPath[] = "/Create/Account/Email",
                  kUpdateAccountPath[] = "/Update/Account",
                  kRetrieveAccountPath[] = "/Retrieve/Account",
                  kDeleteAccountPath[] = "/Delete/Account",
                  kUpdateEmailPath[] = "/Update/Account/Email",
                  kUpdateStatusPath[] = "/Update/Account/Status";

pair<bool, string> CreateAccountWithEmail(const string &first_name,
                                          const string &last_name,
                                          const string &user_name,
                                          const string &password,
                                          unsigned int quota = 0) {
  if (AuthenticationManager::get_token().empty()) {
    return make_pair(false,
                     "Cannot create an account without authentication.");
  }

  string post_url = service_url + "/" + service_version + kCreateAccountPath;
  vector<pair<string, string> > create_keys;

  create_keys.push_back(make_pair("hs:firstName", first_name));
  create_keys.push_back(make_pair("hs:lastName", last_name));
  create_keys.push_back(make_pair("hs:password", password));
  create_keys.push_back(make_pair("hs:userName", user_name));

  if (quota > 0) {
    stringstream ss;
    ss << quota;
    create_keys.push_back(make_pair("hs:quota", ss.str()));
  }

  pair<bool, string> xml_request = GetCreateRequest(
                                       "Account",
                                       AuthenticationManager::get_token(),
                                       AuthenticationManager::get_domain(),
                                       create_keys);

  // Fail if there was an error constructing the XML request.
  if (!xml_request.first) {
    return xml_request;
  }

  // Otherwise, attempt to execute the POST.
  return ExecutePost(post_url, xml_request.second);
}

pair<bool, string> UpdateAccount(const string &user_name,
                                 const string &first_name,
                                 const string &last_name,
                                 const string &password) {
  if (AuthenticationManager::get_token().empty()) {
    return make_pair(false,
                     "Cannot update an account without authentication.");
  }

  string post_url = service_url + "/" + service_version + kUpdateAccountPath;
  vector<pair<string, string> > update_keys;

  if (!first_name.empty()) {
    update_keys.push_back(make_pair("hs:firstName", first_name));
  }

  if (!last_name.empty()) {
    update_keys.push_back(make_pair("hs:lastName", last_name));
  }

  if (!password.empty()) {
    update_keys.push_back(make_pair("hs:password", password));
  }

  pair<bool, string> xml_request = GetUpdateRequest(
                                       "Account",
                                       AuthenticationManager::get_token(),
                                       AuthenticationManager::get_domain(),
                                       "userName", user_name, update_keys);

  // Fail if there was an error constructing the XML request.
  if (!xml_request.first) {
    return xml_request;
  }

  // Otherwise, attempt to execute the POST.
  return ExecutePost(post_url, xml_request.second);
}

pair<bool, string> RetrieveAccount(const string &user_name) {
  if (AuthenticationManager::get_token().empty()) {
    return make_pair(false,
                     "Cannot retrieve an account without authentication.");
  }

  string post_url = service_url + "/" + service_version + kRetrieveAccountPath;
  pair<bool, string> xml_request = GetRetrieveRequest(
                                       "Account",
                                       AuthenticationManager::get_token(),
                                       AuthenticationManager::get_domain(),
                                       "userName",
                                       user_name);

  // Fail if there was an error constructing the XML request.
  if (!xml_request.first) {
    return xml_request;
  }

  // Otherwise, attempt to execute the POST.
  return ExecutePost(post_url, xml_request.second);
}

pair<bool, string> DeleteAccount(const string &user_name) {
  if (AuthenticationManager::get_token().empty()) {
    return make_pair(false,
                     "Cannot delete an account without authentication.");
  }

  string post_url = service_url + "/" + service_version + kDeleteAccountPath;
  pair<bool, string> xml_request = GetDeleteRequest(
                                       "Account",
                                       AuthenticationManager::get_token(),
                                       AuthenticationManager::get_domain(),
                                       "userName",
                                       user_name);

  // Fail if there was an error constructing the XML request.
  if (!xml_request.first) {
    return xml_request;
  }

  // Otherwise, attempt to execute the POST.
  return ExecutePost(post_url, xml_request.second);
}

pair<bool, string> SetAccountStatus(const string &user_name, bool locked) {
  if (AuthenticationManager::get_token().empty()) {
    return make_pair(false,
                     "Cannot update an account without authentication.");
  }

  string post_url = service_url + "/" + service_version + kUpdateStatusPath;

  vector<pair<string, string> > update_keys;
  update_keys.push_back(make_pair("hs:accountStatus",
                                 (locked ? "locked" : "unlocked")));

  pair<bool, string> xml_request = GetUpdateRequest(
                                       "Account",
                                       AuthenticationManager::get_token(),
                                       AuthenticationManager::get_domain(),
                                       "userName",
                                       user_name,
                                       update_keys);

  // Fail if there was an error constructing the XML request.
  if (!xml_request.first) {
    return xml_request;
  }

  // Otherwise, attempt to execute the POST.
  return ExecutePost(post_url, xml_request.second);
}

} // End of googleapps namespace.
